import * as mockjs from "mockjs";
import * as cryptoJS from 'crypto-js';
import * as moment from "moment";
import * as puppeteer from "puppeteer";
import IConstants from "@/core/constants";
import * as fs from "fs-extra"
import * as readline from "readline"
import { Observable } from "rxjs"
import IGlobal from "./global.service";


const IHelper = new class {
  sleep(milliseconds: number): Promise<number> {
    return new Promise<number>(resolve => {
      setTimeout(() => {
        resolve(1)
      }, milliseconds)
    })
  }
  hash(len?: number, option?: {mixed?: boolean}): string {
    const length: number = len ? len : 6
    const lower: string = "abcdefghighlmnopqrstuvwxyz"
    const upper: string = lower.toUpperCase()
    const number: string = "0123456789"
    const symbol: string = "!@?$%^&*"
    const pool: string = `${number}${upper}${lower}${option?.mixed ? symbol : ""}`
    return mockjs.Random.string(lower, 1) + mockjs.Random.string(pool, length - 1)
  }

  md5(l: string): string {
    return cryptoJS.MD5(l).toString()
  }

  unix(): number {
    return moment().unix()
  }

  convertToQueryString(params: object, ignoreEncode?: boolean): string {
    return Object.keys(params).map(k => `${k}=${ignoreEncode ? params[k] : encodeURIComponent(params[k])}`).join("&")
  }

  parseQueryStr(queryStr: string): {[prop: string]: string} {
    const obj: {[prop: string]: string} = {}
    queryStr.split("&").forEach(e => {
      const [k, v] = e.split("=")
      obj[k] = decodeURIComponent(v)
    })
    return obj
  }

  timeFormatted(format?: string) {
    return moment().format(format || "YYYY-MM-DD HH:mm:ss")
  }

  getArray(len: number): number[] {
    return Array.from(new Array(len).keys())
  }
  getAssetAbsPathByStaticPath(staticPath: string): string {
    return [IConstants.publicDir, ...staticPath.split("/").slice(2)].join("/")
  }

  readFileLines(filepath: string): Observable<string[]> {
    return new Observable<string[]>(observer => {
      const linesArray: string[] = []
      const rl = readline.createInterface({
        input: fs.createReadStream(filepath),
        crlfDelay: Infinity // 适用于 Windows 换行符（'\r\n'）
      })
      // 逐行读取文件内容
      rl.on('line', (line) => {
        // 将每一行添加到数组中
        linesArray.push(line);
      });

      // 监听读取结束事件
      rl.on('close', () => {
        observer.next(linesArray)
        observer.complete()
      });
    })
  }

  covert2StandardCookieStr(cookie: string): string {
    let cookieArray: puppeteer.Protocol.Network.Cookie[] = []
    try {
      cookieArray = JSON.parse(cookie)
      if (!Array.isArray(cookieArray)) {
        cookieArray = []
      }
    } catch(e) {}
    return cookieArray.map(e => `${e.name}=${e.value}`).join("; ")
  }

  getCookieValueFromCookieStr(cookie: string, key: string): string {
    const regex = new RegExp(`${key}=.*?;`, "g"); 
    let matched = cookie.match(regex)
    if (!Array.isArray(matched) || matched.length <= 0) return ""
    return matched[0].replace(";", "").split("=").pop()
  }
  hookTimeAvailable() {
    // return +IGlobal.store?.taskSettings?.autoFetch === 1
    return moment().hours() < 23 && moment().hours() >= 12
  }
}

export default IHelper